package com.ruoyi.web.controller.system;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.core.domain.model.WxLoginUser;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.WeChatUtil;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.*;
import com.ruoyi.system.domain.LoginParams;
import com.ruoyi.system.domain.SysAuthUser;
import com.ruoyi.system.mapper.SysUserMapper;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static com.ruoyi.common.core.domain.AjaxResult.success;

/**
 * 登录控制器
 *
 * @author SK
 * @since 2018/6/13
 */
@RestController
@RequestMapping("/mobile/login")
public class LoginController{

    @Autowired(required = false)
    private TokenService tokenService;

    @Autowired(required = false)
    private MobileLoginService loginService;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private SysLoginService sysLoginService;

    @Resource
    private AuthenticationManager authenticationManager;

    /**
     * 会员登录
     * @return -1 用户名或密码错误  -2 账号冻结  -3 账号锁定 1 成功  -4 验证码错误
     */
    @PostMapping("/loginByPassword")
    @ResponseBody
    public AjaxResult loginByPassword(HttpServletRequest request) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String phoneNo = request.getParameter("phoneNo");
        String validCode = request.getParameter("validCode");
        String loginType = request.getParameter("loginType");
        // 登录结果
        LoginParams loginParams = new LoginParams();
        loginParams.setUsername(username);
        loginParams.setPassword(password);
        loginParams.setPhoneNo(phoneNo);
        loginParams.setValidCode(validCode);
        loginParams.setLoginType(loginType);
        return loginService.login(loginParams);
    }
    /**
     * 发送验证码
     */
    @PostMapping("/sendCode")
    @ResponseBody
    public AjaxResult sendRegisterCode(HttpServletRequest request) {
        String phoneNo = request.getParameter("phoneNo");
        String validCodeType = request.getParameter("validCodeType");
        // 登录结果
        LoginParams loginParams = new LoginParams();
        loginParams.setPhoneNo(phoneNo);
        loginParams.setValidCodeType(validCodeType);
        return loginService.sendCode(loginParams);
    }

    @GetMapping("/logout")
    @ResponseBody
    public AjaxResult logout(HttpServletRequest request) {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if(null != loginUser){
            tokenService.delLoginUser(loginUser.getToken());
        }
        return success("退出成功！");
    }

    @PostMapping("/wx")
    public AjaxResult user_login(@RequestBody WxLoginUser wxLoginUser, HttpServletRequest request) {
        // 用户非敏感信息：rawData 签名：signature
        JSONObject rawDataJson = JSON.parseObject(wxLoginUser.getRawData());
        // 开发者服务器 登录凭证校验接口 appid + appsecret + code 获取用户信息
        JSONObject SessionKeyOpenId = WeChatUtil.getSessionKeyOrOpenId(wxLoginUser.getCode());
        // 3.接收微信接口服务 获取返回的参数
        String openid = SessionKeyOpenId.getString("openid");
        String sessionKey = SessionKeyOpenId.getString("session_key");

        // 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
        String signature2 = DigestUtils.sha1Hex(wxLoginUser.getRawData() + sessionKey);
        if (!wxLoginUser.getSignature().equals(signature2)) {
            return AjaxResult.error("签名校验失败");
        }
        // 5.根据返回的User实体类，判断用户是否是新用户，是的话，将用户信息存到数据库；
        LoginUser tokenUser = tokenService.getLoginUser(request);
        SysUser user = userMapper.selectAuthUserByUuid("wx" + openid);
//        if (StringUtils.isNotNull(tokenUser)) {
//            if (StringUtils.isNotNull(user))
//            {
//                String token = tokenService.createToken(SecurityUtils.getLoginUser());
//                return success().put(Constants.TOKEN, token);
//            }
//        }
        if (StringUtils.isNotNull(user)) {
            LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
            String token = tokenService.createToken(loginUser);

            // 记录登录信息
            sysLoginService.recordLoginInfo(user.getUserId());
            if (StringUtils.isEmpty(user.getUserType())) {
                return success().put(Constants.TOKEN, token)
                        .put("navigateTo", "status/status");
            }
            // 相亲情况跳转
            return success().put(Constants.TOKEN, token);
        }
        SysUser sysUser = new SysUser();
        sysUser.setUserName("wx" + openid);
        sysUser.setNickName(rawDataJson.getString("nickName"));
        userMapper.insertUser(sysUser);
        SysAuthUser authUser = new SysAuthUser("wx" + openid, sysUser.getUserId(), openid, rawDataJson.getString("nickName"), rawDataJson.getString("avatarUrl"), "", "wx");
        userMapper.insertAuthUser(authUser);
        sysLoginService.recordLoginInfo(sysUser.getUserId());

        LoginUser loginUser = new LoginUser(sysUser.getUserId(), sysUser.getDeptId(), sysUser, permissionService.getMenuPermission(sysUser));
        String token = tokenService.createToken(loginUser);
        return success().put(Constants.TOKEN, token)
                .put("navigateTo", "status/status");
    }
}
